package com.uzai.console.service.qiniu.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.uzai.common.enums.FileSaveTypeEnum;
import com.uzai.common.enums.MerConfigKeyEnum;
import com.uzai.common.enums.MerConfigTypeEnum;
import com.uzai.common.enums.RedisCacheKeyEnum;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.console.common.utils.CommonUtil;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.dto.qiniu.QiniuConfigDto;
import com.uzai.console.entity.MerBaseConfig;
import com.uzai.console.entity.Qiniu;
import com.uzai.console.mapper.MerBaseConfigMapper;
import com.uzai.console.service.qiniu.QiniuService;
import com.uzai.console.vo.qiniu.QiniuConfig;
import com.uzai.console.vo.qiniu.QiniuConfigInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author jianghan
 * @date 2019-06-18 15:06
 */
@Service
@RefreshScope//刷新nocas配置文件
public class QiniuServiceImpl implements QiniuService {
    private static Logger logger = LoggerFactory.getLogger(QiniuServiceImpl.class);

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MerBaseConfigMapper merBaseConfigMapper;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;

    /**
     * @author jitwxs
     * @date 2022/3/9 15:40
     * @param merId
     * @param inputStream
     * @param fileName
     * @return java.lang.String
     */
    @Override
    public String upload(Long merId, InputStream inputStream, String fileName) {

        String fileUrl = "";

        Qiniu qiniu = getQiniuByMerId(merId);

        if(qiniu == null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请保存七牛云配置");
        }

        //Configuration cfg = new Configuration(Zone.zone0());
        Configuration cfg = new Configuration();
        UploadManager uploadManager = new UploadManager(cfg);
        Auth auth = Auth.create(qiniu.getAccessKey(), qiniu.getSecretKey());
        String upToken = auth.uploadToken(qiniu.getBucketName());
        try {
            Response response = uploadManager.put(inputStream,fileName,upToken,null, null);
            DefaultPutRet putRet = JSONObject.parseObject(response.bodyString(), DefaultPutRet.class);
            String key = putRet.key;
            /**加密
            if (qiniu.getAccessKey().equals("Vckxul9gQaj_feHpv9pUUfLsUuk-Sk1XR2v6zJLD")){
                // 加密
                try {
                    byte[] pwdbyte = AESCode.encrypt(key, "xcq666888!@~", 16);
                    key = AESCode.parseByte2HexStr(pwdbyte);
                } catch (Exception e) {
                    logger.error("err:{}",e);
                }
            }
             **/
            fileUrl =  qiniu.getDomain()+ "/" +key;
        } catch (QiniuException ex) {
            Response r = ex.response;
            logger.error(r.toString());
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "上传失败");
        }
        return fileUrl;
    }

    /**
     *
     * @author jitwxs
     * @date 2022/3/9 15:37
     * @param merId
     * @return com.uzai.console.entity.Qiniu
     */
    @Override
    public Qiniu getQiniuByMerId(Long merId) {
        String qiniuStr = (String) redisTemplate.opsForValue().get(String.format(RedisCacheKeyEnum.QINIU_CONFIG.getKey(), merId));
        if(StringUtils.isNotBlank(qiniuStr)){
            Qiniu qiniu = JSONObject.parseObject(qiniuStr, Qiniu.class);
            return qiniu;
        }else{
            //从数据库当中查询
            MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(merId, MerConfigKeyEnum.QINIU_CONFIG.getValue());
            if(merBaseConfig != null && StringUtils.isNotBlank(merBaseConfig.getVal())){
                Qiniu qiniu = JSONObject.parseObject(merBaseConfig.getVal(), Qiniu.class);
                return qiniu;
            }else { //数据库当中也没有，则判断类型type,
//                if(Tools.getInteger(type) == 0) {
//                    Qiniu qiniu = new Qiniu();
//                    qiniu.setAccessKey(uzaiConsoleSysConfig.getQiniuAK());
//                    qiniu.setSecretKey(uzaiConsoleSysConfig.getQiniuSK());
//                    qiniu.setBucketName(uzaiConsoleSysConfig.getQiniuSpace());
//                    qiniu.setDomain(uzaiConsoleSysConfig.getQiniuNetAddress());
//                    return qiniu;
//                }else {
                    throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请先配置七牛云");
//                }
            }
        }
    }

    /**
     * 验证七牛配置信息是否正确
     * @author jitwxs
     * @date 2022/1/18 14:25
     * @param qiniuConfigDto
     */
    public Boolean checkConfig(QiniuConfigDto qiniuConfigDto){

        Boolean checkFlag = false;

        if(StringUtils.isBlank(qiniuConfigDto.getAccessKey())){
            throw new BusinessException(ResponseCode.PARAMETER_EXCEPTION, "七牛云AK不能为空");
        }

        if(StringUtils.isBlank(qiniuConfigDto.getSecretKey())){
            throw new BusinessException(ResponseCode.PARAMETER_EXCEPTION, "七牛云SK不能为空");
        }

        if(StringUtils.isBlank(qiniuConfigDto.getBucketName())){
            throw new BusinessException(ResponseCode.PARAMETER_EXCEPTION, "七牛云存储空间不能为空");
        }

        if(StringUtils.isBlank(qiniuConfigDto.getDomain())){
            throw new BusinessException(ResponseCode.PARAMETER_EXCEPTION, "七牛云域名不能为空");
        }
        try{
            String domain = qiniuConfigDto.getDomain();
            domain = domain.replace("http://","");
            domain = domain.replace("https://","");
            domain = domain.replace("/","");
            Configuration cfg = new Configuration(Zone.zone0());
            Auth auth = Auth.create(qiniuConfigDto.getAccessKey(), qiniuConfigDto.getSecretKey());
            BucketManager bucketManager = new BucketManager(auth,cfg);
            String[] buckets = bucketManager.buckets();

            for (String bucket:buckets){
                if (bucket.equals(qiniuConfigDto.getBucketName())){
                    String[] domains = bucketManager.domainList(bucket);
                    for (String dm:domains){
                        if (dm.equals(domain)){
                            checkFlag = true;
                        }
                    }
                }
            }
        }catch (Exception e){
            logger.error("--is error;  error={}",e.getMessage());
        }
        return checkFlag;
    }

    /**
     * 保存七牛云配置信息
     * @author jitwxs
     * @date 2022/1/18 14:25
     * @param qiniuConfigDto
     */
    @Transactional
    public void addQiniuConfig(QiniuConfigDto qiniuConfigDto){

        Boolean checkFlag = checkConfig(qiniuConfigDto);

        Integer now = DateUtil.getNowTime();

        if(checkFlag){//验证成功，才能保存

            Qiniu qiniu = new Qiniu();
            BeanUtils.copyProperties(qiniuConfigDto, qiniu);

            MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(qiniuConfigDto.getMerId(), MerConfigKeyEnum.QINIU_CONFIG.getValue());
            if(merBaseConfig != null){ //修改
                merBaseConfig.setVal(Tools.getStrEmpty(JSONObject.toJSONString(qiniu)));
                merBaseConfig.setUpdateTime(now);
                merBaseConfigMapper.update(merBaseConfig);
            }else{//新增
                merBaseConfig = new MerBaseConfig();
                merBaseConfig.setId(IdWorker.getId());
                merBaseConfig.setMerId(qiniuConfigDto.getMerId());
                merBaseConfig.setType(MerConfigTypeEnum.PRODUCTS.getValue());
                merBaseConfig.setKey(MerConfigKeyEnum.QINIU_CONFIG.getValue());

                merBaseConfig.setVal(Tools.getStrEmpty(JSONObject.toJSONString(qiniu)));
                merBaseConfig.setCreateTime(now);
                merBaseConfig.setUpdateTime(now);
                merBaseConfigMapper.insert(merBaseConfig);
            }
            //保存到redis缓存中
            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.QINIU_CONFIG.getKey(), qiniuConfigDto.getMerId()), Tools.getStrEmpty(JSONObject.toJSONString(qiniu)));


            //是否默认
            Integer isDefault =  Tools.getInteger(qiniuConfigDto.getIsDefault());
            //文件存储类型
            MerBaseConfig merBaseConfig_fileSaveType = merBaseConfigMapper.selectByMerId(qiniuConfigDto.getMerId(), MerConfigKeyEnum.FILE_SAVE_TYPE.getValue());
            if(merBaseConfig_fileSaveType != null){ //存在，则修改
                if(isDefault.intValue() == 1){ //默认启用七牛云
                    merBaseConfig_fileSaveType.setVal(String.valueOf(FileSaveTypeEnum.QINIU.getId()));
                    merBaseConfig_fileSaveType.setUpdateTime(now);
                    merBaseConfigMapper.update(merBaseConfig_fileSaveType);
                }else{ //不启用,判断旧启用是否采用七牛云，如果是，则修改成未配置，如果不是，则不操作
                    if(Tools.getStr(merBaseConfig_fileSaveType.getVal()).equals(String.valueOf(FileSaveTypeEnum.QINIU.getId()))){
                        merBaseConfig_fileSaveType.setVal(String.valueOf(FileSaveTypeEnum.NOCONFIG.getId()));
                        merBaseConfig_fileSaveType.setUpdateTime(now);
                        merBaseConfigMapper.update(merBaseConfig_fileSaveType);
                    }
                }
            }else{//新增
                merBaseConfig_fileSaveType = new MerBaseConfig();
                merBaseConfig_fileSaveType.setId(IdWorker.getId());
                merBaseConfig_fileSaveType.setMerId(qiniuConfigDto.getMerId());
                merBaseConfig_fileSaveType.setType(MerConfigTypeEnum.PRODUCTS.getValue());
                merBaseConfig_fileSaveType.setKey(MerConfigKeyEnum.FILE_SAVE_TYPE.getValue());
                if(isDefault.intValue() == 1){ //启用
                    merBaseConfig_fileSaveType.setVal(String.valueOf(FileSaveTypeEnum.QINIU.getId()));
                }else{
                    merBaseConfig_fileSaveType.setVal(String.valueOf(FileSaveTypeEnum.NOCONFIG.getId()));
                }
                merBaseConfig_fileSaveType.setCreateTime(now);
                merBaseConfig_fileSaveType.setUpdateTime(now);
                merBaseConfigMapper.insert(merBaseConfig_fileSaveType);
            }

            //保存到redis缓存中
            redisTemplate.opsForValue().set(String.format(RedisCacheKeyEnum.FILE_SAVE_TYPE.getKey(), qiniuConfigDto.getMerId()), merBaseConfig_fileSaveType.getVal());
        }else{
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "配置错误");
        }
    }

    /**
     * 上传文件
     * @author liuqi
     * @date 2022/1/18 15:17
     * @return com.uzai.console.vo.qiniu.QiniuConfigUploadFileVo
     */
    public String uploadFile(MultipartFile multipartFile, Long merId){

        if(multipartFile == null){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择文件");
        }

        String fileUrl = "";
        String filename = multipartFile.getOriginalFilename();
        filename = CommonUtil.getUUID() + filename.substring(filename.lastIndexOf("."), filename.length());
        try {
            fileUrl = upload(merId, multipartFile.getInputStream(), filename);
        } catch (IOException e) {
            logger.error("--is error; error={}", e.getMessage());
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "上传失败");
        }
        return fileUrl;
    }

    /**
     * 查询七牛云详情
     * @author jitwxs
     * @date 2022/1/18 17:25
     * @param merId
     * @return com.uzai.console.vo.qiniu.QiniuConfigVo
     */
    public QiniuConfigInfoVo findQiniuConfigInfo(Long merId){
        QiniuConfigInfoVo qiniuConfigInfoVo = new QiniuConfigInfoVo();
        MerBaseConfig merBaseConfig = merBaseConfigMapper.selectByMerId(merId, MerConfigKeyEnum.QINIU_CONFIG.getValue());
        if(merBaseConfig != null){
            QiniuConfig qiniuConfig = JSONObject.parseObject(merBaseConfig.getVal(), QiniuConfig.class);
            if(qiniuConfig != null){
                BeanUtils.copyProperties(qiniuConfig, qiniuConfigInfoVo);
            }
        }

        //是否默认存储
        qiniuConfigInfoVo.setIsDefault(0); //默认未启用
        MerBaseConfig merBaseConfig_fileSaveType = merBaseConfigMapper.selectByMerId(merId, MerConfigKeyEnum.FILE_SAVE_TYPE.getValue());
        if(merBaseConfig_fileSaveType != null){
            if(String.valueOf(FileSaveTypeEnum.QINIU.getId()).equals(merBaseConfig_fileSaveType.getVal())){ //启用七牛云
                qiniuConfigInfoVo.setIsDefault(1);
            }
        }

        return  qiniuConfigInfoVo;
    }

}